package com.anmingle.pswb.service.impl;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import com.anmingle.enums.ErrorCode;
import com.anmingle.exception.BusinessException;
import com.anmingle.pswb.entity.LoginUser;
import com.anmingle.pswb.mapper.UserMapper;
import com.anmingle.pswb.model.entity.User;
import com.anmingle.pswb.service.UserService;

import com.anmingle.pswb.service.LoginService;
import com.anmingle.utils.MatcherUtils;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import static com.anmingle.pswb.service.LoginService.getLoginUser;

/**
 * @author 安明乐
 * @Title UserServiceImpl
 * @Package IntelliJ IDEA
 * @date 2022/11/18 16:58
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {


    //@Resource
    //private AuthenticationManager authenticationManager;

    @Resource
    private UserMapper userMapper;


    private static final String KEY = "anmingle123";

    //每日登录人数
    private static final Map<Long, Integer> DATA_PER = new ConcurrentHashMap<>();

    public static Map<Long, Integer> getLoginDateUser() {
        return DATA_PER;
    }
    public static Map<Long, Integer> clearLoginDateUser() {
        DATA_PER.clear();
        return DATA_PER;
    }

    //每日登录人数
    //private static final Map<Long, Integer> DATA_PER = new ConcurrentHashMap<>();

    private record UserResponse(String phone, String name, String image, String openid) {
    }

    @Override
    public boolean loginOut() {

        StpUtil.logout();

        return true;
    }

    @Override
    public Map<String, Object> login(String user, String password) {

        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StringUtils.isNotBlank(user), "user", user);

        User user1 = userMapper.selectOne(queryWrapper);
        if (user1 == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "账号不存在");
        }
        String pas = SaSecureUtil.aesDecrypt(KEY, user1.getPassword());
        if (!pas.equals(password)) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR, "密码错误");
        }


        return ReturnUserResponse(user1);
    }

    @Override
    public long userRegister(String user, String password, String checkPassword, String phone, String name) {
        if (StringUtils.isAnyBlank(user, password, checkPassword, name) || phone == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数为空");
        }
        if (name.length() > 10) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户名过长!");
        }
        if (user.length() < 5) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号过短!");
        }
        if (password.length() < 8 || checkPassword.length() < 8) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码过短!");
        }
        if (!password.equals(checkPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致!");
        }
        //手机号验证
        //"/^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[^]{8,16}$/"
        if (!MatcherUtils.isPhone(phone)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号格式不正确!");
        }
        synchronized (user.intern()) {
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("user", user);
            Long integer = userMapper.selectCount(queryWrapper);
            if (integer > 0) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "账号重复");
            }
            String encode = SaSecureUtil.aesEncrypt(KEY, password);

            User user1 = new User();
            user1.setUser(user);
            user1.setPassword(encode);
            user1.setPhone(phone);
            user1.setName(name);
            boolean save = this.save(user1);
            if (!save) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "注册失败，数据库错误");
            }
            return user1.getId();
        }
    }

    @Override
    public Map<String, Object> WXlogin(String openid, String nickname, String image, String password, String checkPassword, String phone) {
        if (StringUtils.isAnyBlank(openid, nickname, image, password, checkPassword, phone.toString())) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数错误请重新填写!");
        }
        if (nickname.length() > 6) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "昵称过长!");
        }
        if (!MatcherUtils.match("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)[\\s\\S]{8,16}$", password)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码过于简单!");
        }

        if (!checkPassword.equals(password)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致!");
        }

        if (!MatcherUtils.isPhone(phone)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号格式不正确!");
        }

        synchronized (openid.intern()) {

            //aes 对称加密
            String encode = SaSecureUtil.aesEncrypt(KEY, password);

            System.out.println(openid);
            QueryWrapper<User> que = new QueryWrapper<>();
            que.eq("openid", openid);
            User user = userMapper.selectOne(que);
            user.setUser(phone);
            user.setPhone(phone);
            user.setPassword(encode);
            user.setName(nickname);
            user.setImage(image);
            user.setUpdateTime(new Date());

            boolean b = this.updateById(user);
            if (!b) {
                throw new BusinessException(ErrorCode.SYSTEM_ERROR, "服务器内部错误请重试");
            }
            String userid = user.getId().toString();
            //登录
            Map<String, Object> stringObjectMap = ReturnUserResponse(user);
            //把完整的用户信息存入redis  userid作为key
            return stringObjectMap;

        }
    }

    @Override
    public LoginUser getUser() {
        return getLoginUser();
    }


    public static Map<String, Object> ReturnUserResponse(User user) {

        /**
         * 强制登录   可以换成多端登录
         * @param id userid
         */
        String loginId = StpUtil.getTokenValueByLoginId(user.getId());
        //顶下上线的人
        if (StringUtils.isNotBlank(loginId)) {
            StpUtil.logout(user.getId());
        }
        LoginUser user1 = new LoginUser();
        BeanUtils.copyProperties(user, user1);
        LoginService.login(user1);
        SaTokenInfo tokenInfo = StpUtil.getTokenInfo();

        UserResponse userResponse = new UserResponse(user.getPhone().replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2"),
                user.getName(), user.getImage(), user.getOpenid()
                );
        Map<String, Object> map = new HashMap<>();
        if (user.getIsBlacklist() == 1) {
            map.put(tokenInfo.getTokenName(), "黑名单用户");
            return map;
        }


        //登记当日登录的用户
        //inSERTDataper(user);


        map.put(tokenInfo.getTokenName(), tokenInfo.getTokenValue());

        map.put("user", userResponse);

        return map;

    }

    /**
     * 每日用户登录次数
     * @param user
     * 后续完善
     */
    private static void inSERTDataper(User user) {
        Integer integer = DATA_PER.get(user.getId());
        if (integer == null) {
            DATA_PER.put(user.getId(), 1);
        } else {
            DATA_PER.put(user.getId(), integer+1);
        }
    }



}




